<?php
/**
 * 需求调拨申请模型基类；
 * @author shipanpan
 */
class Application_Model_StoryTransferApply extends Model_Base {
	//调拨申请，审核类型
	const SYSTEM_AGREE = 2; //系统审核通过
	const ADMIN_AGREE = 3; //管理员审核通过
	const ADMIN_REJECT = 4; //管理员驳回
	const SYSTEM_REJECT = 5; //系统驳回

	const STATUS = [
		'待审核', '系统审核通过', '审核通过', '审核驳回', '系统自动驳回',
	];

	//依赖的其他模型
	private $_storyModel;
	private $_primaryTeamLeaderStatusModel;

	public function __construct() {
		$this->db = $this->db();
		$this->writeDb = $this->db("write_db");
	}

	/**
	 * 根据产品调拨申请id获取调拨申请详情
	 * @param  int    $transferApplyId [description]
	 * @return [type]                  [description]
	 */
	public function getOneById(int $transferApplyId) {
		return $this->db->fetchRow("select * from b_stock_transfer_apply where id=" . $transferApplyId);
	}

	/**
	 * 根据产品调出，调入仓获取调拨申请记录
	 * @param  [type] $goodsSn               goods_sn
	 * @param  [type] $fromTransferWarehouse 调出仓
	 * @param  [type] $toTransferWarehouse   调入仓
	 * @param  [type] $applyDate             调拨申请时间
	 * @return [type]                        [description]
	 */
	public function getOne($goodsSn, $fromTransferWarehouse, $toTransferWarehouse, $applyDate = null, $useWriteDb = false) {
		if (is_null($applyDate)) {
			$applyDate = date("Y-m-d");
		}

		$db = ($useWriteDb) ? $this->writeDb : $this->db;

		$where = $db->quoteInto("goods_sn=?", $goodsSn);
		$where .= " AND " . $db->quoteInto("from_warehouse=?", $fromTransferWarehouse);
		$where .= " AND " . $db->quoteInto("to_warehouse=?", $toTransferWarehouse);
		$where .= " AND " . $db->quoteInto("create_date=?", $applyDate);

		return $db->fetchRow('select * from b_stock_transfer_apply where ' . $where);
	}

	/**
	 * 审核通过调拨申请
	 * @param  int    $transferApplyId [description]
	 * @param  int    $checkType       	2系统审核通过 ;3管理员审核通过
	 * @return [type]                  [description]
	 */
	protected function _agree(int $transferApplyId, int $checkType) {
		$this->_storyModel || $this->_storyModel = new Application_Model_Story();
		if (!in_array($checkType, [self::ADMIN_AGREE, self::SYSTEM_AGREE])) {
			return $this->_error('产品调拨申请，现在只支持人工和系统审核！');
		}
		$transferApply = $this->getOneById($transferApplyId);
		if (empty($transferApply)) {
			return $this->_error('未找到调拨申请记录！');
		}
		if ($transferApply['status'] != '待审核') {
			return $this->_error('调拨申请记录不是待审核状态！不能进行审核通过操作！');
		}

		$applyTransferId = $transferApply['id'];
		$needTransferQuantity = $transferApply['apply_quantity'];
		$canTransferQuantity = $transferApply['can_transfer_quantity'];

		$checkPassQuantity = min($needTransferQuantity, $canTransferQuantity);
		$applyTransferBelongStory = $this->writeDb->fetchRow("select * from b_story where id=" . $transferApply['story_id'] . " AND delete_flag=0");
		if (!$applyTransferBelongStory) {
			return $this->_error("未找到产品调拨申请所属备货需求！");
		}

		if ($applyTransferBelongStory['examine_status'] != Application_Model_Story::INIT_EXAMINE_STATUS) {
			return $this->_error("调拨申请所属备货需求审核状态:" . $applyTransferBelongStory['examine_status'] . "异常！");
		}
		$storyId = $applyTransferBelongStory['id'];

		//需求数量更新；因为可以从其他仓库调拨，需要更新实际采购数量的数据
		$backupStoryUpdate = [];
		//备货需求调拨日志;
		$storyTransferLog = [
			'after_transfer_a_story_quantity' => $applyTransferBelongStory['a_story_quantity'],
			'after_transfer_b_story_quantity' => $applyTransferBelongStory['b_story_quantity'],
			'after_transfer_c_story_quantity' => $applyTransferBelongStory['c_story_quantity'],
		];

		$this->writeDb->beginTransaction();

		$storyUpdateWhere = $this->writeDb->quoteInto('id = ?', $storyId);
		$storyIsNotDelete = true;
		try {
			if ($canTransferQuantity >= $needTransferQuantity) {
				$backupStoryUpdate = ['a_story_quantity' => 0, 'c_story_quantity' => 0];
				if (!$applyTransferBelongStory['b_story_quantity']) {
					$this->_storyModel->delete($storyId);
					$storyIsNotDelete = false;
				}
			} else {
				//如果仓库可调拨库存小于总需要调拨库存，优先调拨给a需求
				if ($canTransferQuantity >= $applyTransferBelongStory['a_story_quantity']) {
					$backupStoryUpdate['a_story_quantity'] = 0;
					$cStoryCanTransferNum = $canTransferQuantity - $applyTransferBelongStory['a_story_quantity'];
					if ($cStoryCanTransferNum) {
						$backupStoryUpdate['c_story_quantity'] = $applyTransferBelongStory['c_story_quantity'] - $cStoryCanTransferNum;
					}
				} else {
					$aStoryCanTransferNum = $applyTransferBelongStory['a_story_quantity'] - $canTransferQuantity;
					$backupStoryUpdate = ['a_story_quantity' => $aStoryCanTransferNum];
				}
			}
			if ($backupStoryUpdate && $storyIsNotDelete) {
				//更新需求数量
				if (isset($backupStoryUpdate['a_story_quantity'])) {
					$updateReason = "可调拨数量:" . $checkPassQuantity;
					$updateQuantityResult = $this->_storyModel->updateQuantity($storyId, Application_Model_Story::A_STORY_TYPE, $backupStoryUpdate['a_story_quantity'], $updateReason, 'system', false);
					$storyTransferLog['after_transfer_a_story_quantity'] = $backupStoryUpdate['a_story_quantity'];
				}
				if (isset($backupStoryUpdate['c_story_quantity'])) {
					$updateReason = "可调拨数量:" . $checkPassQuantity;
					$updateQuantityResult = $this->_storyModel->updateQuantity($storyId, Application_Model_Story::C_STORY_TYPE, $backupStoryUpdate['c_story_quantity'], $updateReason, 'system', false);
					$storyTransferLog['after_transfer_c_story_quantity'] = $backupStoryUpdate['c_story_quantity'];
				}
				if ($updateQuantityResult === false) {
					$this->writeDb->rollBack();
					return $this->_error($this->_storyModel->getErrorMsg());
				}
			}

			//记录需求调拨日志
			$storyTransferLogWhere = $this->writeDb->quoteInto('stock_transfer_apply_id = ?', $transferApplyId);
			$this->writeDb->update("b_story_transfer_log", $storyTransferLog, $storyTransferLogWhere);

			//更新调拨申请状态
			$transferApplyWhere = $this->writeDb->quoteInto('id = ?', $transferApplyId);
			$afterCheckStatus = ($checkType == self::ADMIN_AGREE) ? "审核通过" : '系统审核通过';
			$this->writeDb->update("b_stock_transfer_apply", ['status' => $afterCheckStatus, 'check_pass_quantity' => $checkPassQuantity], $transferApplyWhere);

			//检查需求数量是否满足自动审核通过标准
			if ($storyIsNotDelete) {
				$primaryTeamLeaderStatusModel = new Application_Model_StoryStatus_PrimaryTeamLeaderStatus($storyId);
				if ($primaryTeamLeaderStatusModel->needCheck()) {
					$statusUpdateResult = $this->_storyModel->statusUpdate($storyId, Application_Model_Story::WAIT_PRIMARY_TEAM_LEADER_EXAMINE, false);
				} else {
					$statusUpdateResult = $this->_storyModel->statusUpdate($storyId, Application_Model_Story::EXAMINE_PASS, false);
				}
				if ($statusUpdateResult === false) {
					$this->writeDb->rollBack();
					return $this->_error($this->_storyModel->getErrorMsg());
				}
			}

			$this->writeDb->commit();
			return true;
		} catch (Exception $e) {
			$this->writeDb->rollBack();
			return $this->_error($e->getMessage());
		}
	}

	/**
	 * 驳回调拨申请
	 * @param  int    $transferApplyId [description]
	 * @param  int    $checkType       	 4 管理员驳回; 5 系统驳回
	 * @return [type]                  [description]
	 */
	protected function _reject(int $transferApplyId, int $checkType) {
		$this->_storyModel || $this->_storyModel = new Application_Model_Story();
		if (!in_array($checkType, [self::ADMIN_REJECT, self::SYSTEM_REJECT])) {
			return $this->_error('产品调拨申请，现在只支持人工和系统审核！');
		}

		$transferApply = $this->getOneById($transferApplyId);
		if (empty($transferApply)) {
			return $this->_error('未找到调拨申请记录！');
		}
		if ($transferApply['status'] != '待审核') {
			return $this->_error('调拨申请记录不是待审核状态！不能进行驳回操作！');
		}

		$applyTransferBelongStory = $this->getApplyTransferStory($transferApplyId);
		if (!$applyTransferBelongStory) {
			return $this->_error("未找到产品调拨申请所属备货需求！");
		}
		$storyId = $applyTransferBelongStory['id'];
		$this->writeDb->beginTransaction();
		try {
			$afterCheckStatus = ($checkType == self::ADMIN_REJECT) ? "审核驳回" : '系统自动驳回';
			$where = $this->writeDb->quoteInto('id = ?', $transferApplyId);
			$this->writeDb->update("b_stock_transfer_apply", ['status' => $afterCheckStatus, 'check_pass_quantity' => 0], $where);

			//记录备货需求调拨日志;
			$storyTransferLog = [
				'after_transfer_a_story_quantity' => $applyTransferBelongStory['a_story_quantity'],
				'after_transfer_b_story_quantity' => $applyTransferBelongStory['b_story_quantity'],
				'after_transfer_c_story_quantity' => $applyTransferBelongStory['c_story_quantity'],
			];
			$storyTransferLogWhere = $this->writeDb->quoteInto('stock_transfer_apply_id = ?', $transferApplyId);
			$this->writeDb->update("b_story_transfer_log", $storyTransferLog, $storyTransferLogWhere);

			//检查需求数量是否满足自动审核通过标准
			$primaryTeamLeaderStatusModel = new Application_Model_StoryStatus_PrimaryTeamLeaderStatus($storyId);
			if ($primaryTeamLeaderStatusModel->needCheck()) {
				$this->_storyModel->statusUpdate($storyId, Application_Model_Story::WAIT_PRIMARY_TEAM_LEADER_EXAMINE, false);
			} else {
				$this->_storyModel->statusUpdate($storyId, Application_Model_Story::EXAMINE_PASS, false);
			}

			$this->writeDb->commit();
			return true;
		} catch (Exception $e) {
			$this->writeDb->rollBack();
			return $this->_error($e->getMessage());
		}
	}

	/**
	 * 根据调拨需求所属的备货需求详情
	 * @param  [type] $applyTransferId [description]
	 * @return [type]                  [description]
	 */
	public function getApplyTransferStory($applyTransferId) {
		$applyTransferStoryId = $this->getApplyTransferStoryId($applyTransferId);
		if (!$applyTransferStoryId) {
			return $this->_error("未找到调拨需求所属备货需求ID！");
		}
		return $this->db->fetchRow("select * from b_story where id= ? ", $applyTransferStoryId);
	}

	/**
	 * 获取申请调拨所属的备货需求id
	 * @return [type] [description]
	 */
	public function getApplyTransferStoryId(int $applyTransferId) {
		return $this->db->fetchOne("select story_id from b_stock_transfer_apply where id = ?", $applyTransferId);
	}

	protected function _getApplyByStatus($status) {
		return $waitCheckApplyList = $this->db->query("select * from b_stock_transfer_apply where status=" . $this->db->quote($status) . " and create_date=" . $this->db->quote(date("Y-m-d")))->fetchAll();
	}

}